---
title: .family
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

এটি পড়ার আগে, [providers](../../concepts/providers) এবং
[কীভাবে সেগুলি পড়তে হয়](../../concepts/reading) সম্পর্কে পড়ার বিবেচনা করুন।

এই অংশে, আমরা `.family` প্রদানকারী মডিফায়ার সম্পর্কে বিস্তারিত আলোচনা করব।

`.family` সংশোধকের একটি উদ্দেশ্য আছে: বাহ্যিক ভ্যালু থেকে একটি প্রভাইডার তৈরি করা।

`family`-এর জন্য কিছু সাধারণ ব্যবহার-ক্ষেত্র হবেঃ

- [FutureProvider] এর আইডি থেকে একটি `Message` আনতে `.family` এর সাথে সংযুক্ত করা
- একটি প্রদানকারীর কাছে বর্তমান `Locale` পাস করা, যাতে আমরা অনুবাদগুলি পরিচালনা করতে পারি

## ব্যবহারবিধি

families গুলা যেভাবে কাজ করে তা হল প্রভাইডারে একটি অতিরিক্ত প্যারামিটার যোগ করা। 
এই প্যারামিটার তারপর অবাধে কিছু স্টেট তৈরি করতে আমাদের প্রভাইডারে ব্যবহার করা যেতে পারে।

উদাহরণস্বরূপ, আমরা `family` আর  [FutureProvider] একত্রিত করে একটি `Message` ফেচ
করতে পারি এর ID ব্যবহার করেঃ

```dart
final messagesFamily = FutureProvider.family<Message, String>((ref, id) async {
  return dio.get('http://my_api.dev/messages/$id');
});
```

তারপর, আপনার `messagesFamily` প্রভাইডারটি ব্যবহার করার সময়, সিনট্যাক্সটি সামান্য পরিবর্তিত হয়। স্বাভাবিক সিনট্যাক্স আর কাজ করবে নাঃ

```dart
Widget build(BuildContext context, WidgetRef ref) {
  // Error – messagesFamily is not a provider
  final response = ref.watch(messagesFamily);
}
```

পরিবর্তে, আমাদের `messagesFamily`-এ একটি প্যারামিটার পাস করতে হবেঃ

```dart
Widget build(BuildContext context, WidgetRef ref) {
  final response = ref.watch(messagesFamily('id'));
}
```

:::info

একযোগে বিভিন্ন প্যারামিটার সহ একটি `family` ব্যবহার করা সম্ভব।
উদাহরণস্বরূপ, আমরা একই সময়ে ফরাসি এবং ইংরেজি উভয় অনুবাদ পড়তে একটি `titleFamily` ব্যবহার করতে পারিঃ

```dart
@override
Widget build(BuildContext context, WidgetRef ref) {
  final frenchTitle = ref.watch(titleFamily(const Locale('fr')));
  final englishTitle = ref.watch(titleFamily(const Locale('en')));

  return Text('fr: $frenchTitle en: $englishTitle');
}
```

:::

## প্যারামিটার সীমাবদ্ধতা

`familiy`-গুলা সঠিকভাবে কাজ করার জন্য, এটি গুরুত্বপূর্ণ যে একটি প্রভাইডারে পাস করা প্যারামিটারের জন্য 
একটি সামঞ্জস্যপূর্ণ `hashCode` এবং `==` থাকা দরকার।

আদর্শভাবে, প্যারামিটারটি হয় একটি আদিম হওয়া উচিত (bool/int/double/String),
একটি কন্সটেন্ট (প্রভাইডার), বা একটি অপরিবর্তনীয় বস্তু যা `==` এবং `hashCode` ওভাররাইড করে।

### `autoDispose` এর ব্যবহার __করা উচিত__  যখন প্যারামিটারটি কন্সটেন্ট নয়:

আপনি আপনার প্রভাইডারের কাছে একটি সার্চ ফিল্ডের ইনপুট পাস করার জন্য families ব্যবহার করতে চাইতে পারেন।
কিন্তু সেই ভ্যালুটি প্রায়শই পরিবর্তিত হতে পারে এবং কখনও পুনরায় ব্যবহার করা উচিত নয়।
এটি মেমরি লিকের কারণ হতে পারে কারণ ডিফল্টরূপে, একটি প্রভাইডার কখনও ধ্বংস হয় না
যদি আর ব্যবহার না করা হয়।

`.family` এবং `.autoDispose` উভয়ই ব্যবহার করে সেই মেমরি লিক ঠিক করেঃ

```dart
final characters = FutureProvider.autoDispose.family<List<Character>, String>((ref, filter) async {
  return fetchCharacters(filter: filter);
});
```

## একটি family-তে একাধিক প্যারামিটার পাস করা

একটি প্রভাইডারকে একাধিক মান পাস করার জন্য families-এ কোনও অন্তর্নির্মিত সমর্থন নেই৷

অন্যদিকে, সেই ভ্যালু _যেকোনো কিছু_ হতে পারে (যতক্ষণ না এটি পূর্বে উল্লেখিত বিধিনিষেধের সাথে মেলে)।

This includes:

- একটি tuple যা [tuple](http://pub.dev/packages/tuple) হতে
- [Freezed] দ্বারা জেনেরেটেড অবজেক্ট অথবা [built_value](https://pub.dev/packages/built_value)
- [equatable](https://pub.dev/packages/equatable) ব্যবহার করা অবজেক্ট

এখানে [Freezed] এবং [equatable] ব্যবহার করে একটি উদাহরণ রয়েছে:

<Tabs
  groupId="family"
  defaultValue="freezed"
  values={[
    { label: 'Freezed', value: 'freezed', },
    { label: 'Equatable', value: 'equatable', },
  ]}
>

<TabItem value="freezed">

```dart
@freezed
abstract class MyParameter with _$MyParameter {
  factory MyParameter({
    required int userId,
    required Locale locale,
  }) = _MyParameter;
}

final exampleProvider = Provider.autoDispose.family<Something, MyParameter>((ref, myParameter) {
  print(myParameter.userId);
  print(myParameter.locale);
  // userId/locale দিয়ে কিছু করুন
});

@override
Widget build(BuildContext context, WidgetRef ref) {
  int userId; // userId অন্য কোথাও থেকে পড়ুন
  final locale = Localizations.localeOf(context);

  final something = ref.watch(
    exampleProvider(MyParameter(userId: userId, locale: locale)),
  );

  ...
}
```

</TabItem>
<TabItem value="equatable">

```dart
class MyParameter extends Equatable  {
  MyParameter({
    required this.userId,
    required this.locale,
  });

  final int userId;
  final Locale locale;

  @override
  List<Object> get props => [userId, locale];
}

final exampleProvider = Provider.family<Something, MyParameter>((ref, myParameter) {
  print(myParameter.userId);
  print(myParameter.locale);
  // userId/locale দিয়ে কিছু করুন
});

@override
Widget build(BuildContext context, WidgetRef ref) {
  int userId; // userId অন্য কোথাও থেকে পড়ুন
  final locale = Localizations.localeOf(context);

  final something = ref.watch(
    exampleProvider(MyParameter(userId: userId, locale: locale)),
  );

  ...
}
```
</TabItem>
</Tabs>

[freezed]: https://pub.dev/packages/freezed
[equatable]: https://pub.dev/packages/equatable
[futureprovider]: ../../providers/future_provider
